﻿using System;
using GeoAPI.Geometries;
using NetTopologySuite.Algorithm;

namespace NetTopologySuite.Geometries.Utilities
{
	public static class AffineTransformationFactory
	{
		public static AffineTransformation CreateFromControlVectors(Coordinate src0, Coordinate src1, Coordinate src2, Coordinate dest0, Coordinate dest1, Coordinate dest2)
		{
			return new AffineTransformationBuilder(src0, src1, src2, dest0, dest1, dest2).GetTransformation();
		}

		public static AffineTransformation CreateFromControlVectors(Coordinate src0, Coordinate src1, Coordinate dest0, Coordinate dest1)
		{
			Coordinate tip = new Coordinate(dest1.X - dest0.X, dest1.Y - dest0.Y);
			double theta = AngleUtility.AngleBetweenOriented(src1, src0, tip);
			double num = src1.Distance(src0);
			double num2 = dest1.Distance(dest0);
			if (num == 0.0)
			{
				return null;
			}
			double num3 = num2 / num;
			AffineTransformation affineTransformation = AffineTransformation.TranslationInstance(-src0.X, -src0.Y);
			affineTransformation.Rotate(theta);
			affineTransformation.Scale(num3, num3);
			affineTransformation.Translate(dest0.X, dest0.Y);
			return affineTransformation;
		}

		public static AffineTransformation CreateFromControlVectors(Coordinate src0, Coordinate dest0)
		{
			double x = dest0.X - src0.X;
			double y = dest0.Y - src0.Y;
			return AffineTransformation.TranslationInstance(x, y);
		}

		public static AffineTransformation CreateFromControlVectors(Coordinate[] src, Coordinate[] dest)
		{
			if (src.Length != dest.Length)
			{
				throw new ArgumentException("Src and Dest arrays are not the same length");
			}
			if (src.Length == 0)
			{
				throw new ArgumentException("Too few control points");
			}
			if (src.Length > 3)
			{
				throw new ArgumentException("Too many control points");
			}
			if (src.Length == 1)
			{
				return AffineTransformationFactory.CreateFromControlVectors(src[0], dest[0]);
			}
			if (src.Length == 2)
			{
				return AffineTransformationFactory.CreateFromControlVectors(src[0], src[1], dest[0], dest[1]);
			}
			return AffineTransformationFactory.CreateFromControlVectors(src[0], src[1], src[2], dest[0], dest[1], dest[2]);
		}

		public static AffineTransformation CreateFromBaseLines(Coordinate src0, Coordinate src1, Coordinate dest0, Coordinate dest1)
		{
			Coordinate tip = new Coordinate(src0.X + dest1.X - dest0.X, src0.Y + dest1.Y - dest0.Y);
			double theta = AngleUtility.AngleBetweenOriented(src1, src0, tip);
			double num = src1.Distance(src0);
			double num2 = dest1.Distance(dest0);
			if (num == 0.0)
			{
				return new AffineTransformation();
			}
			double num3 = num2 / num;
			AffineTransformation affineTransformation = AffineTransformation.TranslationInstance(-src0.X, -src0.Y);
			affineTransformation.Rotate(theta);
			affineTransformation.Scale(num3, num3);
			affineTransformation.Translate(dest0.X, dest0.Y);
			return affineTransformation;
		}
	}
}
